/* eslint-disable  */
import React, { PureComponent } from 'react';
import { Modal, PickerView, ActivityIndicator } from 'antd-mobile';
import Empty from '../Empty';
import { AbstractPickerProps } from 'antd-mobile/lib/picker/AbstractPicker';
import arrayTreeFilter from 'array-tree-filter';
import classnames from 'classnames';
import { transformLabelValue } from './util';
import requset from '@/utils/request';
import './index.less';
export interface PickerProps extends Omit<AbstractPickerProps, 'data' | 'onChange' | 'cols'> {
  placeholder?: string;
  url?: string;
  dataFormat?: (data) => { label: string; value: number; children?: any[] }[];
  separator: string;
  textFormat?: (data) => string;
  requestOptions?: any;
  /**
   * 请求数据源callback
   */
  onFetchSuccess?: (data) => void;
  onChange?: (value, label, item) => void;
  data?: AbstractPickerProps['data'];
  /**
   * 是否启用缓存
   */
  cache?: boolean;
  autoFill?: boolean;
  labelKey?: string;
  valueKey?: string;
  fetchData?: (current?:any, selected?:any, value?:any) => any;
  /**
   * 默认auto
   * 根据第一个索引的层级深度决定
   */
  cols: number | 'auto';
  id?: any;
}
// export { MyRequestOptionsInit };

interface State {
  data: [];
  loading: boolean;
  visible: boolean;
  cols: number;
}

class Index extends PureComponent<PickerProps, State> {
  static defaultProps = {
    cache: false,
    separator: ' ',
    autoFill: false,
    labelKey: 'label',
    valueKey: 'value',
    cols: 'auto',
  };
  constructor(props) {
    super(props);
    const { value, url, cols } = this.props;
    this.state = {
      visible: false,
      loading: true,
      data: [],
      cols: cols !== 'auto' ? cols : this.deepIndex(this.props.data) || 1,
    };
    this.oldtValue = this.value2Array(value);
    this.currentValue = this.value2Array(value);
    if (url) {
      this.controlled = true;
    }
  }

  controlled = false;
  oldtValue = [];
  currentValue = [];
  hasFetch = false;
  componentDidUpdate(nextProps, prePRops) {
    if (nextProps.value && !this.hasFetch) {
      this.oldtValue = this.value2Array(nextProps.value);
      this.currentValue = this.value2Array(nextProps.value);
      this.handleOpen(false);
      this.hasFetch = true;
    }
  }

  value2Array = (value) => {
    if (!value) return [];
    if (Array.isArray(value)) return value.slice(0, this.state.cols);
    return [value];
  };
  array2Value = (value) => {
    if (value && value.length === 1) return value[0];
    return [...value];
  };
  getSel() {
    const { value, placeholder, disabled } = this.props;

    const data = this.controlled ? this.state.data : this.props.data;

    if (!value) {
      return {
        status: 1,
        value: placeholder || '请选择',
        data: [],
      };
    }

    return this.getValue(value);
  }

  getValue(value) {
    const valueArray = this.value2Array(value);
    const { separator, textFormat } = this.props;

    const data = this.controlled ? this.state.data : this.props.data;
    const treeChildren = arrayTreeFilter(
      data as any,
      (c: any, level) => c.value == valueArray[level],
    );

    let _value = treeChildren.map((v) => v.label).join(separator);
    if (typeof textFormat === 'function') {
      const result = textFormat(treeChildren);
      if (result) {
        _value = result;
      }
    }
    return {
      status: 0,
      value: _value,
      data: treeChildren,
    };
  }

  hanleChange = (value) => {
    this.currentValue = [...value];
  };
  close = () => {
    this.setState({
      visible: false,
    });
  };
  handleDismiss = () => {
    this.close();
    this.currentValue = [...this.oldtValue];
  };
  handleOk = () => {
    const data = this.controlled ? this.state.data : this.props.data;
    this.close();
    if (!Array.isArray(data) || data.length <= 0) return;

    if (
      this.props.value &&
      this.currentValue &&
      JSON.stringify(this.oldtValue) === JSON.stringify(this.currentValue)
    ) {
      return;
    }

    const { value: text, data: item } = this.getValue(this.currentValue);
    if (typeof this.props.onChange === 'function') {
      this.hasFetch = true;
      this.props.onChange(this.array2Value(this.currentValue), text, item);
    }
    this.oldtValue = [...this.currentValue];
  };
  getText = () => {};
  dataFormat = (data) => {
    const { dataFormat, labelKey, valueKey } = this.props;
    if (typeof dataFormat === 'function') {
      const newData = dataFormat(data);
      if (Array.isArray(newData)) return newData;
    }

    if (data.code !== 0 || !Array.isArray(data.data)) return [];
    return transformLabelValue(data.data, { labelKey, valueKey });
  };
  // transformLabelValue = (data) => {
  //   const { labelKey, valueKey } = this.props;
  //   if (labelKey !== 'label' || valueKey !== 'value') {
  //     const deep = (items) => {
  //       items.forEach((item) => {
  //         if (item.children && Array.isArray(item.children) && item.children.length > 0) {
  //           deep(item.children);
  //         }
  //         item.label = item[labelKey];
  //         item.value = item[valueKey];
  //       });
  //     };
  //     deep(data);
  //   }
  //   return data;
  // };

  deepIndex = (data) => {
    let i = 0;
    const deep = (data) => {
      i++;
      if (data.children && data.children[0]) {
        deep(data.children[0]);
      }
    };
    if (data && data[0]) {
      deep(data[0]);
    }
    return i;
  };

  setDefaultValue = (data) => {
    const { autoFill, value } = this.props;

    const { cols } = this.state;
    let values = [];
    if (!value) {
      let i = 1;
      const deep = (data) => {
        if (data.value) {
          values.push(data.value);
        }
        i++;
        if (i <= cols && data.children && data.children[0]) {
          deep(data.children[0]);
        }
      };
      if (data && data[0]) {
        deep(data[0]);
      }

      this.currentValue = values;
      this.oldtValue = [...values];
      /**
       * 如果是自动填充的
       */
      if (autoFill && data && data.length === 1) {
        this.handleOk();
      }
    }
  };
  cacheData = {};
  getSourceData = async () => {
    const { cache, requestOptions = { method: 'get' }, url, onFetchSuccess } = this.props;
    let newRequestOptions;
    if (typeof requestOptions === 'function') {
      newRequestOptions = requestOptions() || { method: 'get' };
    } else {
      newRequestOptions = requestOptions;
    }
    let key = '';
    if (cache) {
      const { data, params } = newRequestOptions;
      key = `${url}${JSON.stringify(data)}${JSON.stringify(params)}`;
      if (this.cacheData[key]) {
        return this.cacheData[key];
      }
    }

    const response = await requset(url, newRequestOptions);
    const data = this.dataFormat(response);

    if (cache) {
      this.cacheData[key] = data;
    }

    if (typeof onFetchSuccess === 'function') {
      onFetchSuccess(response);
    }
    return data;
  };
  handleOpen = async (visible = true) => {
    const { url, disabled, cols, value,fetchData } = this.props;
    if(fetchData && typeof fetchData === 'function'){
      
      const data = await fetchData(value);
      if (data && Array.isArray(data)) {
        this.controlled = true;
        this.handleDefaultValue(data,visible)
         
      }
    }
    
    /**
     * 不是请求的
     */
    if (!url) {
      if (disabled) return;
      this.setDefaultValue(this.props.data);
      return this.setState({
        visible,
      });
    }
    /**
     * 走url请求的
     */
    if (visible && disabled) return;
    this.setState({
      loading: true,
    });
    // 获取数据源
    const data = await this.getSourceData();
    this.handleDefaultValue(data,visible)

    
  };
  /**
     * 打开时候记录下this.currentValue为第一个
     * 用来按确定时候赋值
     */
  handleDefaultValue = (data,visible)=>{
    const { url, disabled, cols } = this.props;
    this.setDefaultValue(data);
    this.setState(
      {
        data,
        cols: cols !== 'auto' ? cols : this.deepIndex(data),
        visible: disabled === true ? false : visible,
        loading: false,
      },
      () => {
        /**
         * 如果visible,代表静默确定，
         * 需要触发下onchange事件
         */
        if (visible === false) {
          const { value: text, data: item } = this.getValue(this.currentValue);
          if (typeof this.props.onChange === 'function') {
            this.props.onChange(this.array2Value(this.currentValue), text, item);
          }
        }
      },
    );
  }
  render() {
    const { status, value } = this.getSel();
    const { visible, data, loading, cols } = this.state;
    const { onChange, autoFill, extra: propsExtra, id, ...props } = this.props;
    const { children, title, dismissText = '取消', okText = '确定' } = this.props;
    let extra;
    if (autoFill) {
      extra = value;
    } else {
      if (!propsExtra) {
        extra = value;
      } else {
        extra = status !== 1 ? value : propsExtra;
      }
    }
    return (
      <div
        className={classnames('hr-picker', {
          'hr-picker-placeholder': status,
          'hr-picker-disabled': props.disabled,
        })}
        id={id}
      >
        {' '}
        <Modal
          popup
          visible={visible}
          animationType="slide-up"
          onClose={() => this.setState({ visible: false })}
        >
          <div className="hr-picker-popup-header">
            <div
              className="hr-picker-popup-item hr-picker-popup-header-left"
              onClick={this.handleDismiss}
            >
              {dismissText}
            </div>
            <div className="hr-picker-popup-item hr-picker-popup-title">{title}</div>
            <div
              className="hr-picker-popup-item hr-picker-popup-header-right"
              onClick={this.handleOk}
            >
              {okText}
            </div>
          </div>
          {this.controlled ? (
            <div className="am-picker-col">
              {loading ? (
                <ActivityIndicator text="加载中" />
              ) : data.length < 0 ? (
                <Empty />
              ) : (
                <PickerView
                  onChange={this.hanleChange}
                  {...props}
                  cols={cols}
                  data={data}
                  value={this.value2Array(this.props.value)}
                ></PickerView>
              )}
            </div>
          ) : (
            <PickerView
              onChange={this.hanleChange}
              {...props}
              cols={cols}
              value={this.value2Array(this.props.value)}
            ></PickerView>
          )}
        </Modal>
        <div onClick={() => this.handleOpen(true)}>
          {children &&
            typeof children !== 'string' &&
            React.isValidElement(children) &&
            React.cloneElement<{ extra?: string }>(children, {
              extra,
            })}
        </div>
      </div>
    );
  }
}

export default Index;

export { transformLabelValue };
